package com.requestfactory.wire.echo;

import java.io.IOException;
import java.math.BigDecimal;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.apache.commons.httpclient.HttpException;

import com.requestfactory.wire.Wire;
import com.requestfactory.wire.WireSkeletonException;
import com.requestfactory.wire.WireStubException;

public class EchoServiceTestCase extends TestCase {

	protected void setUp() throws Exception {
		super.setUp();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}
	
	public void testEchoService() 
	throws WireSkeletonException, WireStubException, EchoServiceException {
		//
		// create and test local echo service
		//
		EchoService echoService = new EchoServiceImpl();
		allTests(echoService);
		//
		// create and test remote echo service
		//
		int port = 2880;
		String context = "/echo";
		EchoService echoServiceStub = Wire.INSTANCE.createStub(
				EchoService.class, 
				"http://localhost:" + port + context);
		Wire.INSTANCE.getSkeleton(port, context).bindService(
				EchoService.class, echoService);
		allTests(echoServiceStub);
	}

	public void allTests(EchoService echoService)
	throws WireSkeletonException, WireStubException, EchoServiceException {
		//
		// Strings
		//
		String localExpected = "Local Hello, World!";
		String localActual = echoService.echo(localExpected);
		Assert.assertEquals(localExpected, localActual);
		String remoteExpected = "Remote Hello, World!";
		String remoteActual = echoService.echo(remoteExpected);
		Assert.assertEquals(remoteExpected, remoteActual);
		//
		// ints
		//
		int left = 10;
		int right = 5;
		int result = echoService.divide(left, right);
		Assert.assertEquals(2, result);
		//
		// runtime exception in skeleton
		//
		try {
			echoService.divide(left, 0); // divide by zero
			Assert.assertTrue(false);
		} catch(ArithmeticException ex) { // catch runtime exception
			Assert.assertTrue(true);
		}
		//
		// exceptions
		//
		try {
			echoService.throwEchoServiceException();
			Assert.assertTrue(false);
		} catch(EchoServiceException ex) {
			Assert.assertTrue(true);
		}
		try {
			echoService.throwIllegalArgumentException(0.0F, "hello");
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			echoService.throwHttpException("hello"); 
			Assert.assertTrue(false);
		} catch(HttpException ex) {
			Assert.assertTrue(true);
		}
		try {
			echoService.throwIOException(5, 7, "autoboxing");
			Assert.assertTrue(false);
		} catch(IOException ex) {
			Assert.assertTrue(true);
		}
		
		//
		// primitives
		//
		//for(int i = 0; i < 1000; ++i) {
		BigDecimal dec = echoService.primitives(Byte.MAX_VALUE, Short.MAX_VALUE,
				'A', 5, -1L, 28.99F, 33.5432D);
		Assert.assertNotNull(dec);
		//}
		//
		// nulls
		//
		String nullActual = echoService.echo(null);
		Assert.assertNull(nullActual);
	}

	public void testIllegalArguments()
	throws WireSkeletonException, WireStubException { 
		EchoService echoService = new EchoServiceImpl();
		//
		// create skeleton illegal arguments 
		//
		try {
			Wire.INSTANCE.getSkeleton(-1, null).bindService(
					EchoService.class, echoService);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.getSkeleton(-1, "").bindService(
					EchoService.class, echoService);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.getSkeleton(9092, null).bindService(
					EchoService.class, echoService);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.getSkeleton(9092, "").bindService(
					null, null);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.getSkeleton(9092, "").bindService(
					null, echoService);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.getSkeleton(9092, "").bindService(
					EchoService.class, null);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		//
		// create stub illegal arguments 
		//
		try {
			Wire.INSTANCE.createStub(null, null);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.createStub(null, "http://localhost:9092/echo");
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.createStub(EchoService.class, null);
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
		try {
			Wire.INSTANCE.createStub(EchoService.class, "");
			Assert.assertTrue(false);
		} catch(IllegalArgumentException ex) {
			Assert.assertTrue(true);
		}
	}

	
}
